home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Frameworks / Sprocket Framework DR2 / Sprocket Framework / AEHandling.cp < prev    next >
Text File  |  1996-06-15  |  20KB  |  824 lines

  1. /*
  2.  
  3.     File:        AppleEventHandling.cp
  4.     Project:    Sprocket Framework 1.1 (DR2), released 6/15/96
  5.     Contains:    Minimalist support for the required and Display Manager AppleEvents
  6.                 We also support openning and printing “LetterSpec” documents for AOCE.
  7.     To Do:        To really support AppleScript™, we’ll need to do ALOT more work in here.
  8.  
  9.     Sprocket Major Contributors:
  10.     ----------------------------
  11.     Dave Falkenburg, producer of Sprocket 1.0
  12.     Bill Hayden,     producer of Sprocket 1.1
  13.     Steve Sisak,     producer of the upcoming Sprocket 2.0
  14.     
  15.     Pete Alexander        Steve Falkenburg    Randy Thelen
  16.     Eric Berdahl        Nitin Ganatra        Chris K. Thomas
  17.     Marshall Clow        Dave Hershey        Leonard Rosenthal
  18.     Tim Craycroft        Dave Mark            Dean Yu
  19.     David denBoer        Gary Powell
  20.     Cameron Esfahani    Jon Summers            Apple Computer, Inc.
  21.         
  22.     Comments, Additions, or Corrections:
  23.     ------------------------------------
  24.     Bill Hayden, Nikol Software <nikol@codewell.com>
  25.  
  26. */
  27.  
  28. #include "Sprocket.h"
  29.  
  30. #ifndef __APPLEEVENTS__
  31.     #include <AppleEvents.h>
  32. #endif
  33.  
  34. #ifndef __AEREGISTRY__
  35.     #include <AERegistry.h>
  36. #endif
  37.  
  38. #ifndef __DISPLAYS__
  39.     #include <Displays.h>            //    for Display Manager AppleEvent constants
  40. #endif
  41.  
  42. #ifndef __PPCTOOLBOX__
  43.     #include <PPCToolbox.h>
  44. #endif
  45.  
  46. #ifndef __EPPC__
  47.     #include <EPPC.h>
  48. #endif
  49.  
  50. #if    qInlineInputAware
  51.     #ifndef __TEXTSERVICES__
  52.         #include <TextServices.h>
  53.     #endif
  54. #endif
  55.  
  56. #include "AEHandling.h"
  57.  
  58.  
  59.  
  60. static pascal Boolean StandardAEIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn);
  61.     
  62.  
  63. AEDesc        gThisProcessDesc;
  64.  
  65.  
  66.  
  67. /*****************************************************************************/
  68.  
  69.  
  70.  
  71. void InitAppleEventRoutines(void)
  72. {
  73.     ProcessSerialNumber    thisProcess;
  74.  
  75.     //    Create useful AE Targets for our aplication
  76.  
  77.     //    By building the target in this fashion, we get the best performance
  78.     //    out of the AppleEvent manager because it can call our event handlers
  79.     //    inline.
  80.  
  81.     thisProcess.highLongOfPSN     = 0;
  82.     thisProcess.lowLongOfPSN     = kCurrentProcess;
  83.     (void) AECreateDesc(typeProcessSerialNumber, (Ptr)&thisProcess, sizeof(ProcessSerialNumber), &gThisProcessDesc);
  84.  
  85.  
  86.     //    It’s probably more efficient to use a table to install these handlers…
  87.     
  88.     (void) AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(HandleOpenApplication), 0, false);
  89.     (void) AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc(HandleOpenDocuments), 0, false);
  90.     (void) AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, NewAEEventHandlerProc(HandlePrintDocuments), 0, false);
  91.     (void) AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(HandleQuitApplication), 0, false);
  92.  
  93.     //    regardless of whether or not we have the display manager, go ahead and register an AppleEvent handler
  94.  
  95.     (void) AEInstallEventHandler(kCoreEventClass, kAESystemConfigNotice, NewAEEventHandlerProc(HandleSystemConfigNotice), 0, false);
  96.  
  97.     //    It’s probably more efficient to use a table to install these handlers…
  98.     
  99.     (void) AEInstallEventHandler(kSprocketCommandClass, kProcessOneCommand, NewAEEventHandlerProc(HandleSprocketCommand), 0, false);
  100.  
  101. #if    qInlineInputAware
  102.     if (gHasTextServices)
  103.         {
  104.         (void) AEInstallEventHandler(kTextServiceClass, kUpdateActiveInputArea, NewAEEventHandlerProc(HandleTextServicesUpdateActiveInputArea), 0, false);
  105.         (void) AEInstallEventHandler(kTextServiceClass, kPos2Offset, NewAEEventHandlerProc(HandleTextServicesPos2Offset), 0, false);
  106.         (void) AEInstallEventHandler(kTextServiceClass, kOffset2Pos, NewAEEventHandlerProc(HandleTextServicesOffset2Pos), 0, false);
  107.         //    we don’t need to handle <kTextServiceClass, kShowHideInputWindow> events
  108.         }
  109. #endif
  110. }
  111.  
  112.  
  113.  
  114. /*****************************************************************************/
  115.  
  116.  
  117.  
  118. OSErr CheckAppleEventForMissingParams(AppleEvent *theAppleEvent)
  119. {
  120.     DescType    returnedType;
  121.     Size        actualSize;
  122.     OSErr        err;
  123.     
  124.     err = AEGetAttributePtr(theAppleEvent,keyMissedKeywordAttr,typeWildCard,
  125.                             &returnedType,nil,0,&actualSize);
  126.     
  127.     if (err == errAEDescNotFound)        //    If we couldn’t find the error attribute
  128.         return noErr;                    //        everything is ok, return noErr
  129.     
  130.     if (err == noErr)                    //    We found an error attribute, so
  131.         return errAEEventNotHandled;    //        tell the client we ignored the event
  132.  
  133.     return err;                            //    Something else happened, return it
  134. }
  135.  
  136.  
  137.  
  138. /*****************************************************************************/
  139.  
  140.  
  141.  
  142. OSErr ChooseApplicationAsAETarget(AEAddressDesc *targetDesc, StringPtr prompt)
  143. {
  144.     PortInfoRec        thePortInfo;
  145.     LocationNameRec    theLocation;
  146.     TargetID        theTargetID;
  147.     OSErr            err;
  148.  
  149.     err = PPCBrowser(prompt, "\p", false, &theLocation, &thePortInfo, (PPCFilterUPP) NULL, "\p");
  150.     if (err == noErr)
  151.         {
  152.         theTargetID.name = thePortInfo.name;
  153.         theTargetID.location = theLocation;
  154.  
  155.         err = AECreateDesc(typeTargetID, &theTargetID, sizeof(theTargetID), targetDesc);
  156.         }
  157.  
  158.     return err;
  159. }
  160.  
  161.  
  162.  
  163.  
  164. /*****************************************************************************/
  165.  
  166.  
  167.  
  168. AEIdleUPP        StandardAEIdleUPP = NewAEIdleProc(StandardAEIdleProc);
  169.  
  170. static pascal Boolean
  171. StandardAEIdleProc(EventRecord *theEvent, long * /* sleepTime */, RgnHandle * /* mouseRgn */)
  172. {
  173.     HandleEvent(theEvent);            //    First, always hand event off to our event handling code
  174.     return false;                    
  175. }
  176.  
  177.  
  178.  
  179.  
  180. /*****************************************************************************/
  181.  
  182.  
  183.  
  184.  
  185. OSErr ForEachDocumentInList(AEDescList documentList,
  186.                             EachDocumentProcPtr documentProc,
  187.                             void * documentParam)
  188. {
  189.     long                documentCount,documentIndex;
  190.     DescType            returnedType;
  191.     Size                actualSize;
  192.     FSSpec                theFSSpec;
  193.     AEKeyword            keyword;
  194.     OSErr                err;
  195.  
  196.     if ((err = AECountItems(&documentList, &documentCount)) != noErr)
  197.         return err;
  198.     
  199.     for (documentIndex=1; documentIndex <= documentCount; documentIndex++)
  200.         {
  201.         err = AEGetNthPtr(&documentList, documentIndex, typeFSS, &keyword, &returnedType,
  202.                                 (Ptr) &theFSSpec, sizeof(theFSSpec), &actualSize);
  203.  
  204.         if (err == noErr)
  205.             (*documentProc)(&theFSSpec, documentParam);
  206.         else
  207.             break;
  208.         }
  209.     
  210.     return    err;
  211. }
  212.  
  213.  
  214.  
  215. /*****************************************************************************/
  216.  
  217.  
  218.  
  219. #pragma mark ••• Required Events Support •••
  220.  
  221.  
  222. pascal OSErr HandleOpenApplication(AppleEvent *theAppleEvent,AppleEvent * /*reply*/,long /*refCon*/)
  223. {
  224.     OSErr    err;
  225.     
  226.     if ((err = CheckAppleEventForMissingParams(theAppleEvent)) != noErr)
  227.         return err;
  228.  
  229.     return(CreateNewDocument());
  230. }
  231.  
  232.  
  233.  
  234. /*****************************************************************************/
  235.  
  236.  
  237.  
  238.  
  239. pascal OSErr HandleOpenDocuments(AppleEvent* theAppleEvent, AppleEvent* /*reply*/, long /*refCon*/)
  240. {
  241.     AEDescList            documentList;
  242.     OSErr                err;
  243.     
  244.     if ((err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &documentList)) != noErr)
  245.         return err;
  246.  
  247.     if ((err = CheckAppleEventForMissingParams(theAppleEvent)) != noErr)
  248.         return err;
  249.  
  250.     err = ForEachDocumentInList(documentList, &OpenDocument, nil);
  251.     (void) AEDisposeDesc(&documentList);
  252.     return err;
  253. }
  254.  
  255.  
  256.  
  257.  
  258. /*****************************************************************************/
  259.  
  260.  
  261.  
  262.  
  263. pascal OSErr HandlePrintDocuments(AppleEvent *theAppleEvent, AppleEvent * /*reply*/, long /*refCon*/)
  264. {
  265.     AEDescList            documentList;
  266. #if    qUseQuickDrawGX
  267.     AEDescList            desktopPrinterList;
  268.     FSSpec                thePrinterFSSpec;
  269.     Boolean                draggedToDesktopPrinter = false;
  270. #endif
  271.     OSErr                err;
  272.     
  273.     if ((err = AEGetParamDesc(theAppleEvent,keyDirectObject,typeAEList,&documentList)) != noErr)
  274.         return err;
  275.  
  276. #if    qUseQuickDrawGX
  277.     if (noErr == AEGetAttributeDesc(theAppleEvent, keyOptionalKeywordAttr, typeAEList, &desktopPrinterList))
  278.         draggedToDesktopPrinter = true;
  279. #endif
  280.  
  281.     if ((err = CheckAppleEventForMissingParams(theAppleEvent)) != noErr)
  282.         return err;
  283.  
  284. #if    qUseQuickDrawGX
  285.     if (draggedToDesktopPrinter)
  286.         {
  287.         DescType            returnedType;
  288.         Size                actualSize;
  289.         AEKeyword            keyword;
  290.  
  291.         err = AEGetNthPtr(&desktopPrinterList, 1, typeFSS, &keyword, &returnedType,
  292.                             (Ptr) &thePrinterFSSpec, sizeof(thePrinterFSSpec), &actualSize);
  293.  
  294.         (void) AEDisposeDesc(&desktopPrinterList);
  295.         }
  296.     err = ForEachDocumentInList(documentList, &PrintDocument, draggedToDesktopPrinter ? &thePrinterFSSpec : NULL);
  297.     (void) AEDisposeDesc(&documentList);
  298. #else
  299.     err = ForEachDocumentInList(documentList, &PrintDocument, nil);
  300. #endif
  301.  
  302.     return err;
  303. }
  304.  
  305.  
  306.  
  307. /*****************************************************************************/
  308.  
  309.  
  310.  
  311.  
  312. pascal OSErr HandleQuitApplication(AppleEvent *theAppleEvent,AppleEvent * /* reply */,long /* refCon */)
  313. {
  314.     OSErr    err;
  315.     
  316.     if ((err = CheckAppleEventForMissingParams(theAppleEvent)) != noErr)
  317.         return err;
  318.  
  319.     gDone = QuitApplication();
  320.     
  321.     if (gDone)
  322.         return noErr;
  323.     else
  324.         return userCanceledErr;
  325. }
  326.  
  327.  
  328.  
  329. /*****************************************************************************/
  330.  
  331.  
  332.  
  333. #pragma mark ••• Sprocket Suite Support •••
  334.  
  335. OSErr SendCommandToSelf(CommandID theCommand)
  336. {
  337.     OSErr                err;
  338.     AEAddressDesc        theTarget;
  339.     AppleEvent            quitAE, replyAE;
  340.     ProcessSerialNumber    psn;
  341.  
  342.  
  343.     if (!gHasAppleScript)    // don't bother recording, just queue the command and return
  344.         {
  345.         err = QueueCommand(theCommand);
  346.         return err;
  347.         }
  348.         
  349.     psn.highLongOfPSN     = 0;
  350.     psn.lowLongOfPSN     = kCurrentProcess;
  351.  
  352.     err = AECreateDesc(typeProcessSerialNumber,
  353.                        (Ptr)&psn,
  354.                        sizeof(ProcessSerialNumber),
  355.                        &theTarget);
  356.  
  357.     if (err == noErr)
  358.         {
  359.         err = AECreateAppleEvent(kSprocketCommandClass, kProcessOneCommand, &theTarget,
  360.                                  kAutoGenerateReturnID, kAnyTransactionID, &quitAE);
  361.                                  
  362.         if (err == noErr)
  363.             {
  364.             err = AEPutParamPtr( &quitAE, keyDirectObject, typeLongInteger,
  365.                         (Ptr)(&theCommand), sizeof(CommandID) );
  366.             }
  367.  
  368.         if (err == noErr)
  369.             {
  370.             err = AESend(&quitAE, &replyAE, kAENoReply + kAECanInteract,
  371.                          kAENormalPriority, 3600, NULL, NULL);
  372.             }
  373.         
  374.         err = AEDisposeDesc(&theTarget);
  375.         }
  376.         
  377.     return err;
  378. }
  379.  
  380.  
  381.  
  382. /*****************************************************************************/
  383.  
  384.  
  385.  
  386. pascal OSErr HandleSprocketCommand(AppleEvent* theAppleEvent, AppleEvent* /*reply*/, long /*refCon*/)
  387. {
  388.     CommandID            theCommand;
  389.     OSErr                err;
  390.     long                actualSize;
  391.     DescType            actualType;
  392.     
  393.     
  394.     err = AEGetParamPtr(theAppleEvent, keyDirectObject, typeLongInteger, &actualType,
  395.                         (UInt32 *)&theCommand, sizeof(UInt32), &actualSize);
  396.     if (err)
  397.         return err;
  398.     
  399.     err = CheckAppleEventForMissingParams(theAppleEvent);
  400.     
  401.     if (err)
  402.         return err;
  403.     
  404.     err = QueueCommand(theCommand);
  405.     
  406.     return err;
  407. }
  408.  
  409.  
  410.  
  411. /*****************************************************************************/
  412.  
  413.  
  414.  
  415. #pragma mark ••• Display Manager Support •••
  416.  
  417. static OSErr HandleDeviceChange(DisplayIDType displayID, Rect *newRect);
  418. static Boolean OutOfBoundsRect(GDHandle gd, WindowRef window, Rect screenRect);
  419. static void MoveInbounds(WindowRef window, GDHandle gd, Rect screenRect);
  420. static void ResizeInbounds(WindowRef window, GDHandle gd, Rect screenRect);
  421. static GDHandle GetGreatestDevice(WindowRef window);
  422. static void GetWindowRect(WindowRef window, Rect *windRect);
  423. static void ResetStdState(WindowRef window);
  424.  
  425. #define kFudgeFactor        4        // fudge factor for boundary around window
  426. #define kTitleBarHeight        18        // title bar height
  427.  
  428.  
  429.  
  430. pascal OSErr
  431. HandleSystemConfigNotice(AppleEvent *event, AppleEvent * /* reply */,long /* refCon */)
  432. {
  433.     OSErr                    err;
  434.     GrafPtr                    oldPort;
  435.     AEDescList                displayList;
  436.     AEDescList                aDisplay;
  437.     AERecord                oldConfig,newConfig;
  438.     AEKeyword                tempWord;
  439.     DisplayIDType            displayID;
  440.     unsigned long            returnType;
  441.     long                    count;
  442.     Rect                    oldRect, newRect;
  443.     
  444.     GetPort(&oldPort);
  445.  
  446.     // Get a list of the displays from the Display Notice AppleEvent.
  447.     err = AEGetParamDesc(event, kAEDisplayNotice, typeWildCard, &displayList);
  448.     // How many items in the list
  449.     err = AECountItems(&displayList,&count);
  450.     
  451.     while (count > 0)
  452.         {     // Loop through the list.
  453.         err = AEGetNthDesc(&displayList, count, typeWildCard, &tempWord, &aDisplay);
  454.         
  455.         // Get the Old Rect.            
  456.         err = AEGetNthDesc(&aDisplay, 1, typeWildCard, &tempWord, 
  457.                            &oldConfig);
  458.         err = AEGetParamPtr(&oldConfig, keyDeviceRect, typeWildCard, 
  459.                           &returnType, &oldRect, 8, nil);
  460.         
  461.         // Get the DisplayID so we can get the GDevice later.                
  462.         err = AEGetParamPtr(&oldConfig, keyDisplayID, typeWildCard, 
  463.                           &returnType, &displayID, 8, nil);
  464.  
  465.         // Get the New Rect.                
  466.         err = AEGetNthDesc(&aDisplay, 2, typeWildCard, &tempWord, &newConfig);
  467.         err = AEGetParamPtr(&newConfig, keyDeviceRect, typeWildCard, 
  468.                           &returnType, &newRect, 8, nil);
  469.         
  470.         // If the New and Old rects are not the same then we can assume
  471.         // the GDevice has changed and we need to rearrange the windows.
  472.         
  473.         if (err == noErr && !EqualRect(&newRect, &oldRect))
  474.             HandleDeviceChange(displayID, &newRect);
  475.  
  476.         count--;
  477.         err = AEDisposeDesc(&aDisplay);
  478.         err = AEDisposeDesc(&oldConfig);
  479.         err = AEDisposeDesc(&newConfig);
  480.         }
  481.     
  482.     err = AEDisposeDesc(&displayList);
  483.     SetPort(oldPort);
  484.     
  485.     return err;
  486. }
  487.  
  488.  
  489.  
  490. /*****************************************************************************/
  491.  
  492. //----------------------------------------------------------------------
  493. //
  494. //    HandleDeviceChange - called when the oldconfig is different from 
  495. //                         newconfig. Will check all windows on effected 
  496. //                           device and move if needed.
  497. //----------------------------------------------------------------------
  498.  
  499. static OSErr HandleDeviceChange(DisplayIDType displayID, Rect *newRect)
  500. {
  501.     OSErr        err = noErr;
  502.     GDHandle    gd;
  503.     GDHandle    onGD;
  504.     WindowRef    window;
  505.     Rect        oldRect = *newRect;    // save it for AdjustWindowSize
  506.     
  507.     // Get the GDevice from the DisplayID.
  508.     
  509.     err = DMGetGDeviceByDisplayID((DisplayIDType) displayID, &gd, false);
  510.  
  511.     if (err == noErr && gd != nil)
  512.         {
  513.         window = FrontWindow();
  514.         
  515.         while (window != nil)
  516.             {
  517.             SetPortWindowPort(window); 
  518.             // which device holds the greatest portion of the window
  519.             onGD = GetGreatestDevice(window);
  520.             
  521.             // If the window is not 50% or greater on
  522.             // the desired device then pass it up.
  523.             if (onGD == gd)
  524.                 { 
  525.                 if (OutOfBoundsRect(gd, window, *newRect))
  526.                     {
  527.                     MoveInbounds(window, gd, *newRect); 
  528.                     if (OutOfBoundsRect(gd, window, *newRect))
  529.                         {
  530.                         ResizeInbounds(window, gd, *newRect);
  531.                         
  532.                         // If it is one of our document windows then we need
  533.                         // to reset the std state and the scroll bars.
  534.                         TWindow*    thisWindow = GetWindowObject(window);
  535.                         
  536.                         if (thisWindow)
  537.                             thisWindow->AdjustForNewWindowSize(&oldRect, newRect);
  538.                         }        
  539.                     }
  540.                     
  541.                 ResetStdState(window);
  542.                 }
  543.                 
  544.             window = GetNextWindow(window);
  545.             }
  546.         }
  547.     
  548.     return err;
  549.     
  550. }
  551.  
  552.  
  553.  
  554. /*****************************************************************************/
  555.  
  556.  
  557.  
  558. //    Check to see if the window is out of the device rect.
  559.  
  560. static Boolean OutOfBoundsRect(GDHandle gd, WindowRef window, Rect screenRect)
  561. {
  562.     Boolean        out = false;
  563.     Rect        windRect;
  564.     short        mHeight = 0;
  565.     
  566.     GetWindowRect(window, &windRect);
  567.     
  568.     if (gd == GetMainDevice())
  569.         mHeight = GetMBarHeight();
  570.  
  571.     if ((windRect.right > screenRect.right) || (windRect.bottom > screenRect.bottom))
  572.         out = true;
  573.  
  574.     if ((windRect.left < screenRect.left) || (windRect.top < screenRect.top + mHeight))
  575.         out = true;
  576.     
  577.     return out;
  578.     
  579. }
  580.     
  581.     
  582.  
  583. /*****************************************************************************/
  584.  
  585.  
  586.  
  587. //    Move window onto the desired device
  588.  
  589. static void MoveInbounds(WindowRef window, GDHandle gd, Rect screenRect)
  590. {
  591.     Rect        bounds;
  592.     short        mHeight = 0;
  593.     short        hGlobal;
  594.     short        vGlobal;
  595.         
  596.     GetWindowRect(window, &bounds);
  597.  
  598.     if (gd == GetMainDevice())
  599.         mHeight = GetMBarHeight();
  600.         
  601.     hGlobal = bounds.left;
  602.     vGlobal = bounds.top + kTitleBarHeight;
  603.     
  604.     // We want to make the left-top a priority so adjust it first
  605.     // as to override the bottom, right movements. This is so we
  606.     // can resize the window later. 
  607.     
  608.     if (((bounds.right - bounds.left) > (screenRect.right - screenRect.left)) ||
  609.         ((bounds.bottom - bounds.top) > 
  610.         ((screenRect.bottom - screenRect.top) - mHeight)))
  611.         {
  612.         
  613.         // adjust left
  614.         if (bounds.left < screenRect.left)
  615.             hGlobal = screenRect.left + kFudgeFactor;
  616.         
  617.         // adjust top
  618.         if (bounds.top < screenRect.top + mHeight)
  619.             vGlobal = screenRect.top + kTitleBarHeight + mHeight + kFudgeFactor;
  620.  
  621.         }    
  622.     else
  623.         {
  624.         // adjust left
  625.         if (bounds.left < screenRect.left)
  626.             hGlobal = screenRect.left + kFudgeFactor;
  627.         else
  628.             {
  629.             // adjust right
  630.             if (bounds.right > screenRect.right)
  631.                 hGlobal = (screenRect.right - (bounds.right - bounds.left)) - kFudgeFactor;
  632.             }
  633.         
  634.         // adjust top
  635.         if (bounds.top < screenRect.top + mHeight)
  636.             vGlobal = screenRect.top + kTitleBarHeight + mHeight + kFudgeFactor;
  637.  
  638.         else {
  639.             // adjust bottom
  640.             if (bounds.bottom > screenRect.bottom)
  641.                 vGlobal = (screenRect.bottom -  kFudgeFactor -
  642.                             (bounds.bottom - bounds.top) + mHeight);
  643.             }        
  644.  
  645.     }
  646.     
  647.     MoveWindow(window, hGlobal, vGlobal,false);
  648.         
  649. }
  650.     
  651.  
  652.  
  653.  
  654. /*****************************************************************************/
  655.  
  656.  
  657.  
  658. //    Resize the window to fit in the graphics device
  659.  
  660. static void ResizeInbounds(WindowRef window, GDHandle gd, Rect screenRect)
  661. {
  662.     Rect        windRect;
  663.     short        h;
  664.     short        v;
  665.  
  666.  
  667.     windRect = (GetWindowPort(window))->portRect;
  668.     
  669.     // make the window bounds the size of the gdRect less the fudge factor.
  670.     
  671.     h = windRect.right - windRect.left;
  672.     v = windRect.bottom - windRect.top;
  673.  
  674.     if (h > screenRect.right - screenRect.left)
  675.         h = ((screenRect.right - screenRect.left) - (kFudgeFactor * 2));
  676.     
  677.     if (v > screenRect.bottom - screenRect.top)
  678.         {
  679.         v = ((screenRect.bottom - screenRect.top) - (kFudgeFactor * 2));
  680.         
  681.         // If we are on the main device then subtract the mBar
  682.         // height plus a fudge factor for a boundary.
  683.         
  684.         if (gd == GetMainDevice())
  685.             v -= (GetMBarHeight() + kTitleBarHeight);
  686.         }        
  687.  
  688.     SizeWindow(window, h, v, true);
  689. }
  690.     
  691.  
  692.  
  693.  
  694. /*****************************************************************************/
  695.  
  696.  
  697.  
  698. //    Find thw device that holds the greatest area of the window.
  699.  
  700. static GDHandle GetGreatestDevice(WindowRef window)
  701. {
  702.     GDHandle    gd;
  703.     GDHandle    savedGD;
  704.     Rect        gdRect;
  705.     Rect        foundRect;
  706.     long        size;
  707.     long        greatest = nil;
  708.  
  709.  
  710.     gd = DMGetFirstScreenDevice(dmOnlyActiveDisplays);
  711.     savedGD = gd;
  712.     
  713.     // Loop through the device list
  714.     
  715.     while (gd != nil)
  716.         {    
  717.         gdRect = (**gd).gdRect;
  718.         
  719.         GlobalToLocal(&TopLeft(gdRect));
  720.         GlobalToLocal(&BotRight(gdRect));
  721.         
  722.         if (SectRect(&(GetWindowPort(window))->portRect, &gdRect, &foundRect))
  723.             {
  724.             size = ((long)(foundRect.right - foundRect.left) * 
  725.                    (long)(foundRect.bottom - foundRect.top));
  726.             
  727.             if (size > greatest)
  728.                 {
  729.                 greatest = size;
  730.                 savedGD = gd;        // save the greatest device
  731.                 }    
  732.             }
  733.             
  734.         gd = DMGetNextScreenDevice(gd, dmOnlyActiveDisplays);
  735.         }
  736.     
  737.     return savedGD;
  738. }
  739.  
  740.  
  741.  
  742.  
  743. /*****************************************************************************/
  744.  
  745.  
  746.  
  747. //    Return the actual window rect in global coords
  748.  
  749. static void GetWindowRect(WindowRef window, Rect *windRect)
  750. {    
  751.     *windRect = (GetWindowPort(window))->portRect;
  752.     
  753.     // add the titlebar height for actual height
  754.     
  755.     windRect->top -= kTitleBarHeight;
  756.     
  757.     LocalToGlobal(&TopLeft(*windRect));
  758.     LocalToGlobal(&BotRight(*windRect));
  759. }
  760.  
  761.  
  762.  
  763.  
  764. /*****************************************************************************/
  765.  
  766.  
  767. //    Since we are now on a different size screen we need
  768. //    to change the stdState window size so our zooming will work properly.  
  769.  
  770. static void ResetStdState(WindowRef window)
  771. {
  772.     Rect        screenRect;
  773.     
  774.     screenRect = (GetWindowPort(window))->portRect;
  775.  
  776.     LocalToGlobal(&TopLeft(screenRect));
  777.     LocalToGlobal(&BotRight(screenRect));
  778.             
  779.     SetWindowStandardState(window, &screenRect);
  780. }
  781.  
  782.  
  783.  
  784. /*****************************************************************************/
  785.  
  786.  
  787.  
  788. #pragma mark ••• Inline Input Support •••
  789.  
  790. #if    qInlineInputAware
  791.  
  792. pascal OSErr
  793. HandleTextServicesUpdateActiveInputArea(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon)
  794. {
  795.     DebugMessage("\pTextServicesUpdateActiveInputArea");
  796.     return errAEEventNotHandled;            //    we really don’t handle this yet...
  797. }
  798.  
  799.  
  800.  
  801. /*****************************************************************************/
  802.  
  803.  
  804. pascal OSErr
  805. HandleTextServicesPos2Offset(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon)
  806. {
  807.     DebugMessage("\pTextServicesPos2Offset");
  808.     return errAEEventNotHandled;            //    we really don’t handle this yet...
  809. }
  810.     
  811.  
  812.  
  813. /*****************************************************************************/
  814.  
  815.  
  816. pascal OSErr
  817. HandleTextServicesOffset2Pos(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon)
  818. {
  819.     DebugMessage("\pTextServicesOffset2Pos");
  820.     return errAEEventNotHandled;            //    we really don’t handle this yet...
  821. }
  822.  
  823. #endif
  824.